類似於mutation
action -> mutation -> 改變狀態 vs 直接提交mutation -> 改變狀態
透過action提交原因:
action 可包含非同步
操作
接受 context 進行操作
context.commit
context.state
context.getters
簡化寫法
actions: {
addTodo ({ commit }) {
commit('addTodo') //提交 mutation
}
}
action 透過dispatch 方法進行分發。
store.dispatch('addTodo')
Action 待入payload參數
actions: {
addTodoAsync ({ commit }, todo) {
setTimeout(() => {
commit('addTodo', todo)
}, 1000)
}
},
也支持以物件形式分發
// 以对象形式分发
store.dispatch({
type: 'addTodoAsync',
todo: this.todo
})
methods: {
add: function () {
this.todo["_id"] = this.totalDone + 1;
this.add("addTodoAsync", this.todo);
},
methods: {
...mapActions([
// this.addTodoAsync(this.todo) -> store.dispatch('addTodoAsync', this.todo)
"addTodoAsync",
]),
// 自定義名稱
...mapActions({
add: "addTodoAsync",
}),
},
},
我們透過action進行非同步操作,那麼控制結束點也格外重要,才能進行下一步動作或是將action進行組合。
Action -> 返回Promise
Promise 非同步操作的結果
完成 resolve() -> then()
失敗 reject() -> catch()
透過 new 實例化
Promise實作方式
return new Promise((resolve, reject) => {...async...resolve()})
透過 then
完成
store.dispatch('addTodoAsync').then(() => {
// next step...
})
組合action
新增待辦後寄出通知信
actions: {
// step1
addThenSend ({ dispatch, commit }) {
return dispatch('addTodoAsync').then(() => {
// step2
commit('sendMessage')
})
}
}
結合await & asyncawait
需包在async
中,官網示例
// getData() & getOtherData() 皆返回 Promise
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
一個dispatch若觸發多個action -> 所以觸發完成 -> 執行Promise
除了已經寫到爛掉的action可執行非同步
,mutation執行同步
,mutation才能修改狀態,其實在payload、map的用法上,兩者是相同的。
雷
: 若透過觸發執行方法中的action或mutation,應避免方法名稱與(action或mutation)名相同,以避免觸發到料想之外的事件。
有錯誤請不吝指教!
參考資料
https://vuejs.org/v2/guide
https://medium.com/itsems-frontend/vue-vuex1-state-mutations-364163b3acac
https://ithelp.ithome.com.tw/articles/10185686
https://ithelp.ithome.com.tw/articles/10237349